home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / PASCAL / ALLSWAGS.ZIP / SWAGG-M.ZIP / MISC.SWG / 0187_Space Lords 7 Video Game - Great Graphic.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-08-30  |  60.8 KB  |  2,257 lines

  1. {
  2. SPACE LORDS 7 - VGA PC VERSION.
  3. (C) 1995 Scott Tunstall & K. Sillett (BBC Maestro)
  4.  
  5. 3 PLAYER ACTION !!!
  6.  
  7. Apologies for the swearing in some of my posts Gayle. To make up
  8. for it, I've given ya a QUALITY video game. Seriously!
  9. It certainly looks smart... don't ask me where I got the graphics
  10. from tho' - some folk may complain! ;)
  11.  
  12. BEFORE YOU RUN THIS PLEASE USE THE XX3402 DECODER ON PART 2 OF
  13. THE SPACE LORDS POST TO CREATE THE FILE IMAGES.ZIP. THEN UNZIP
  14. THE IMAGES FILE INTO WHERE YOUR SPACE LORDS GAME EXECUTABLE FILE
  15. (LORDS.EXE) WILL BE.
  16.  
  17. THEN, RUN THE EXE AND HAVE FUN! :)
  18.  
  19. New game requirements:
  20. ----------------------
  21. 500K of base memory
  22. MCGA/VGA graphics adaptor supporting 320 x 200 x 256 mode
  23. 386 SX 25 processor (at worst) - will run VERY SLOWLY ON THIS MACHINE
  24. (Ok on a 486 DX-2)
  25.  
  26. (Of course, if you are Dave "Stallion Man" Norrie you can use a
  27. 8Mb RAM Pentium f***ing 90 - lucky c***!! I'll put one over him
  28. and buy an IBMRISC 400Mhz baby! (No games for it tho' - I'll change
  29. that !)
  30.  
  31.  
  32. Most importantly a 101 key keyboard is essential.
  33.  
  34.  
  35. PLAYER #     UP      ROTATE LEFT    ROTATE RIGHT     FIRE
  36. -----------------------------------------------------------------
  37. 1            '1'     'A'            'X'              'LEFT SHIFT'
  38. 2            'O'     ';'            '@'              '>'
  39. 3            'Home'  'Keypad 9'     'Keypad -'       'Keypad 3'
  40. 4            JOYSTICK 1      (Not implemented)
  41. 5            JOYSTICK 2      (Not implemented)
  42.  
  43. 6..100 require to be LapLinked (Aye right then)
  44.  
  45. }
  46.  
  47.  
  48.  
  49.  
  50. {$DEFINE FULLDISPLAY}   { <-- $UNDEF if using a slow 386 }
  51. {$DEFINE BUMPING}       { <-- Player to player bumping }
  52. {$DEFINE BONUSES}       { <-- Want Any bonuses on screen }
  53. {$DEFINE MESSAGES}      { <-- This may be silly of you to $UNDEF. }
  54.  
  55.  
  56. {$a+,b-,s-,e+,n+,r-,v-,g+}
  57.  
  58.  
  59. Program SPACE_LORDS_7;   { 7 editions already - GULP! }
  60.  
  61. Uses Dos,NEWGRAPH, NwKBDInt, Crt;
  62.  
  63.      {NEWGRAPH is in JUNE 1996 EDITION OF THE SWAG }
  64.      {AS IS NEWKBDINT - KEYBOARD HANDLER }
  65.  
  66.  
  67.  
  68. Const TopBoundary = -8;          { Top of window }
  69.       BottomBoundary = 204;
  70.       LeftBoundary = -4;
  71.       RightBoundary = 323;
  72.  
  73.  
  74.       MaxPlayers = 3;           { Max no of players on screen at once }
  75.  
  76. {$IFDEF BONUSES}
  77.       MaxBonuses = 6;           { Max no of bonuses on screen at once }
  78. {$ENDIF}
  79.  
  80.       MaxAliens = 10;           { Getting busy on the screen ! }
  81.       MaxStars  = 20;           { Number of parallax stars }
  82.  
  83.  
  84.       MaxExplodeWidth = 200;    { And how far the explosion circles go }
  85.       ShipTurnAngle = 4;        { Degrees that ships turn in }
  86.       PointsForBumping = 500;   { Guess what these are ? }
  87.       PointsForShooting = 100;
  88.       DeductionForShooting = 10;
  89.  
  90.  
  91.       {
  92.       BIT FLAGS - LEAVE ALONE
  93.       }
  94.  
  95.       Dead = 0;                    { Playerstatus defines }
  96.       ShootAble = 1;               { This MUST stay at 1 - V. Important }
  97.       Warping = 2;                 { This MUST stay at 2 ! }
  98.       Exploding = 4;               { This MUST stay at 4 ! }
  99.       Spinning = 8;                { This MUST stay at 8 ! }
  100.       Frozen = 16;
  101.  
  102.       {
  103.       Player Speed stuff
  104.       }
  105.  
  106.       MaxPlayerSpeed = 4;          { This is the MAXIMUM number of
  107.                                    pixels that a player ship jumps
  108.                                    in 1 pass. Pretty fast man }
  109.       SlowestPlayerSpeed = 1;      { The least number of pixel
  110.                                    jumps }
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.       {
  121.       Laser stuff - Alter MaxLasers if you like, leave the rest
  122.       }
  123.  
  124.       MaxLasers = (MaxPlayers * 10)+10;  { How many lasers allocated }
  125.       MaxPlayerLasers = 10;              { How many each player has }
  126.       MaxLaserPower = 5;
  127.  
  128.       NumLaserTypes = 3;           { The current # of laser types }
  129.       LaserFree = 0;
  130.       NormalLaser = 1;             { Lasers stop at edge of screen }
  131.       LaserWraps = 2;              { Lasers can go off one side &
  132.                                    reappear on the other }
  133.       LaserRebound = 3;            { Makes lasers bounce off wall }
  134.  
  135.       PlayerLaserSize = 4;
  136.       AlienLaserSize = 4;
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.       {
  146.       Bonus stuff - don't change the values of the constants
  147.       otherwise some strange effects will occur, OK? If you want
  148.       to add some more stuff you'll have to update BonusString
  149.       too..
  150.       }
  151.  
  152. {$IFDEF BONUSES}
  153.  
  154.       NumberOfBonuses = 13;
  155.  
  156.  
  157. {     BONUS NAME                POINTS FOR COLLECTING IT
  158.       ----------                ------------------------
  159. }
  160.  
  161.       SlowDownBonus = 1;        SlowDownBonusPointsValue = 100;
  162.       EnergyBonus = 2;          EnergyBonusPointsValue = 200;
  163.       FreezeBonus = 3;          FreezeBonusPointsValue = 300;
  164.       ReverseBonus = 4;         ReverseBonusPointsValue = 400;
  165.       DisableBonus = 5;         DisableBonusPointsValue = 500;
  166.       InvulnerabilityBonus = 6; InvulnerabilityBonusPointsValue = 600;
  167.       AssFiringBonus = 7;      AssFiringBonusPointsValue = 700;
  168.       NormalBonus = 8;          NormalBonusPointsValue = 50;
  169.       ToodysBonus = 9;          ToodysBonusPointsValue = 2000;
  170.       LaserBonus = 10;          LaserBonusPointsValue = 200;
  171.       WarpBonus =  11;          WarpBonusPointsValue = 1000;
  172.       BounceLaserBonus = 12;    BounceLaserBonusPointsValue = 200;
  173.  
  174.       UnknownBonus = 13;
  175.  
  176.  
  177. {$ENDIF}
  178.       MaxInvulnerableTime = 200;
  179.  
  180. {$IFDEF BONUSES}
  181.       MaxFrozenTime = 100;
  182.       MaxFireHaltTime = 100;
  183.       MaxKeyReverseTime = 200;
  184.       MaxSlowedDownTime = 100;
  185.       MaxBanzaiTime = 100;
  186.       MaxDisableTime = 100;
  187.  
  188. {$ENDIF}
  189.  
  190.       EnergyIncrement = 5;
  191.       SlowDownIncrement = 10;
  192.       NormalMessageTime = 80;
  193.  
  194.       PacDelayConst = 4;
  195.  
  196.  
  197. {
  198. And now to define ALL aspects of a player's ship
  199. }
  200.  
  201. Type PlayerStruct = Record
  202.  
  203.      PlayerStatus: byte;           { 0 = Dead, 1 = ShootAble, 2= Exploding,
  204.                                    4 = Spinning, 8 = Frozen }
  205.      FrozenTime: word;
  206.  
  207.      ExplodeWidth:byte;
  208.  
  209.      PlayerColour: byte;
  210.  
  211.      PlayerAngle: integer;
  212.      SpinAngle: integer;
  213.  
  214.      SpinSpeed: byte;
  215.      SpinCount: byte;
  216.  
  217.  
  218.      PlayerX: integer;
  219.  
  220.      PlayerY: integer;
  221.  
  222.      PlayerWraps : boolean;
  223.  
  224.      PlayerMessage: String[38];
  225.      MessageTime: byte;
  226.  
  227.      BanzaiTime: word;
  228.  
  229.      {
  230.      Speed stuff
  231.      }
  232.  
  233.      PlayerSpeed: byte;            { Exceed 3 and ship movement is
  234.                                       quite jerky. }
  235.      NormalPlayerSpeed: byte;
  236.      SlowedDownTime: word;
  237.      PlayerWait: byte;
  238.      WaitCount: byte;
  239.      MaxWaitCount: byte;
  240.  
  241.      Thrusting: boolean;
  242.  
  243.  
  244.      PlayerEnergy: integer;
  245.      MaxPlayerEnergy: integer;
  246.      RechargeTime: byte;
  247.      RechargeLatch: byte;
  248.      RechargeDeduction: byte;
  249.  
  250.      KeyReverseTime: byte;
  251.  
  252.      AutoFire: boolean;
  253.  
  254.      DisableTime: byte;
  255.  
  256.      AssFiring : boolean;
  257.  
  258.      FireKeyReleased: boolean;
  259.      FireDelay:byte;
  260.      FireLatch:byte;
  261.  
  262.  
  263.      LaserDeduction: byte;
  264.  
  265.  
  266.      CurrentLaserType: byte;
  267.      CurrentLaserPower: byte;
  268.      CurrentLaserSpeed: byte;
  269.      CurrentMaxLaserTravel: byte;
  270.  
  271.      LaserHurts: boolean;
  272.      EnemyLaserHurts: boolean;
  273.      Invulnerable: boolean;
  274.      InvulnerableTime: word;
  275.  
  276.      PlayerScore: LongInt;
  277.  
  278. End;
  279.  
  280.  
  281. Type Laser = Record
  282.      LaserType: byte;
  283.      FiredBy: byte;
  284.      LaserAngle: integer;
  285.      LaserX: integer;
  286.      LaserY: integer;
  287.      LaserColour: byte;
  288.      LaserSize: byte;
  289.      LaserSpeed: byte;
  290.  
  291.      LaserTravel: byte;
  292.      MaxLaserTravel: byte;
  293.      LaserPower: byte;
  294. End;
  295.  
  296.  
  297. {$IFDEF BONUSES}
  298.  
  299. {
  300. Yeah! Some Pick - Ups for the players!
  301. }
  302.  
  303.  
  304. Type Bonus = Record
  305.      BonusType: byte;
  306.      BonusX: integer;                { Position on screen }
  307.      BonusY: integer;
  308.      BonusXIncrement: integer;
  309.      BonusYIncrement: integer;
  310.      End;
  311.  
  312.  
  313.  
  314. Type BonusArray = Array[1..MaxBonuses] of Bonus;
  315. {$ENDIF}
  316.  
  317.  
  318. Type PlayerArray = Array[1..MaxPlayers] of PlayerStruct;
  319. Type LaserArray = Array[1..MaxLasers] of Laser;
  320.  
  321. Var
  322.  
  323.     PlayerRec: PlayerArray;
  324.     LaserRec: LaserArray;
  325.     TempLaser: Laser;
  326.  
  327. {$IFDEF BONUSES}
  328.     BonusRec: BonusArray;
  329. {$ENDIF}
  330.  
  331.  
  332.     OldKbdInt: procedure;
  333.  
  334.     PlanetSeg,PlanetOfs: word;
  335.     titleBitmapSeg,titleBitmapOfs: word;
  336.     EmporerSeg,EmporerOfs: word;
  337.     ScratchSeg,ScratchOfs: word;
  338.  
  339.     FontSegment, FontOffset: word;
  340.     FontHeight: byte;
  341.  
  342.     PacPointer: Array[0..7] of Pointer;
  343.     AlienPointer: Pointer;
  344.     AlienShapeSize: word;
  345.  
  346.     DestroyerPalette: PaletteType;
  347.     titleBitmapPalette: PaletteType;
  348.     EmporerPalette: PaletteType;
  349.  
  350.  
  351.     TempKey: char;
  352.  
  353.     ColourTable: array[1..MaxPlayers] of byte;
  354.     QCos, QSin : array[0..359] of real;
  355.  
  356.     PlayersOn: byte;
  357.     PlayersAlive: byte;                         { How many players are
  358.                                                   left on the screen -
  359.                                                   initially, PlayersAlive
  360.                                                   equals PlayersOn but
  361.                                                   as people are killed it
  362.                                                   decrements }
  363.     LasersFired: byte;
  364.     LastLaserIndex: byte;
  365.     AlienCount: byte;
  366.  
  367.  
  368.  
  369. {$IFDEF BONUSES}
  370.     BonusesOnScreen: byte;
  371.     BonusString: string[NumberOfBonuses];
  372.  
  373. {$ENDIF}
  374.  
  375.     Message: String[40];
  376.  
  377.  
  378. Procedure Warp(PlayerNo:byte); Forward;
  379.  
  380.  
  381. Procedure LoadGraphics;
  382. Var Count: byte;
  383. Begin
  384.      TextMode(CO80);
  385.      TextBackGround(Black);
  386.      ClrScr;
  387.  
  388.      TextBackGround(Red);
  389.      For Count:=0 to 79 do Write(Chr(32));
  390.  
  391.      TextColor(White);
  392.      Gotoxy(1,1);
  393.      Writeln('SPACE LORDS 7.1.2.3.5.2.9.½  (C) 1994,5 Scott Tunstall.  Lauder College Version');
  394.      Writeln;
  395.      Writeln;
  396.      TextBackGround(Black);
  397.      TextColor(LightGray);
  398.      Writeln('Beginning LORDS_INIT Refresh daemon.. OK.');
  399.      Writeln;
  400.      For Count:=0 to 79 do write('=');
  401.      Writeln('THIS VERSION IS PUBLIC DOMAIN AND MAY BE SWAPPED AND COPIED FREELY');
  402.      Writeln('YOU MAY NOT DISASSEMBLE, REPLICATE OR ALTER THE PROGRAM CODE IN ANY');
  403.      Writeln('WAY UNLESS YOU CONTACT THE AUTHOR.');
  404.      For Count:=0 to 79 do write('=');
  405.  
  406.      Writeln('Please wait.. Loading in PCX files from hard disk..');
  407.      Writeln;
  408.  
  409.      Bitmap(PlanetSeg, PlanetOfs);
  410.      Bitmap(titleBitmapSeg, titleBitmapOfs);
  411.      Bitmap(EmporerSeg, EmporerOfs);
  412.      Bitmap(ScratchSeg, ScratchOfs);
  413.  
  414.  
  415.      Write('DESTROYR.PCX .. ');
  416.  
  417.      SetSourceBitmapAddr(PlanetSeg, PlanetOfs);
  418.      LoadPCX('DESTROYR.PCX',DestroyerPalette);
  419.  
  420.      Writeln('loaded.'); Write('BACK.PCX .. ');
  421.  
  422.      SetSourceBitmapAddr(titleBitmapSeg, titleBitmapOfs);
  423.      LoadPCX('BACK.PCX',titleBitmapPalette);
  424.  
  425.      Writeln('loaded.'); Write('EMPORER.PCX .. ');
  426.  
  427.      SetSourceBitmapAddr(EmporerSeg, EmporerOfs);
  428.      LoadPCX('EMPORER.PCX',EmporerPalette);
  429.  
  430.      Writeln('loaded.');
  431.  
  432.  
  433. End;
  434.  
  435. {
  436. Sorry I had to get rid of the Pascal but I was pissed off
  437. with it's slothfulness !
  438. }
  439.  
  440.  
  441. Procedure BitMapCopy(TheSegment, TheOffset:word);
  442. Begin
  443.      Asm
  444.      MOV AX,DS
  445.      MOV ES,ScratchSeg
  446.      MOV DI,ScratchOfs
  447.      MOV SI,TheOffset
  448.      MOV DS,TheSegment
  449.  
  450.      MOV CX,16000
  451.      REPZ
  452.      DB $66
  453.      MOVSW
  454.      MOV DS,AX
  455.      End;
  456.      SetSourceBitmapAddr(ScratchSeg,ScratchOfs);
  457.      SetDestinationBitmapAddr($a000,0);
  458. End;
  459.  
  460. {========================================================
  461.  
  462. This routine could possibly be slowing the system down
  463. quite a lot as it calls the video interrupt which as most
  464. codies know is as slow as a snail on mogadon. Hmm.
  465.  
  466. I will update this in 1998 when I've got me postgraduate
  467. but right now you'll have to make do with this s**t OK?
  468. }
  469.  
  470.  
  471. Procedure SelectFont(FontNo: byte);
  472. Var TempWidth: byte;
  473. Begin
  474.      UseFont(FontNo);
  475.      GetCurrentFontAddr(FontSegment,FontOffset);
  476.      GetCurrentFontSize(TempWidth,FontHeight);
  477. End;
  478.  
  479.  
  480. {====================
  481.  
  482. Display coloured text
  483.  
  484. }
  485.  
  486.  
  487. Procedure TextXY(x,y:integer;txt:string);
  488. Begin
  489.      SetColour(254);
  490.      OutTextXY(x+1,y+1,txt);
  491.      SetColour(255);
  492.      OutTextXY(x,y,txt);
  493. End;
  494.  
  495.  
  496. {===============================================================
  497.  
  498. This Bresenham circle routine isn't mine. I nicked it from the
  499. SWAG (the rest of the stuff is 100% mine though) and to be quite
  500. honest I couldn't be bothered converting it to assembler, so if
  501. any gurus out there (like me!) want to then they can convert.
  502.  
  503.               *** You'd be sad tho' !! ***
  504. }
  505.  
  506. Procedure Circle(X, Y : integer; Radius:byte);
  507. Var
  508.    Xs, Ys    : Integer;
  509.    Da, Db, S : Integer;
  510.    TX, TR    : word;
  511. begin
  512.      if (Radius = 0) then
  513.           Exit;
  514.  
  515.      if (Radius = 1) then
  516.      begin
  517.           PutPixel(X, Y, GetColour);
  518.           Exit;
  519.      end;
  520.  
  521.      Xs := 0;
  522.      Ys := Radius;
  523.  
  524.      Repeat
  525.            TX:=Sqr(Xs+1);
  526.            TR:=Sqr(Radius);
  527.            Da := TX + Sqr(Ys) - TR;
  528.            Db := TX + Sqr(Ys - 1) - TR;
  529.            S  := Da + Db;
  530.  
  531.            Inc(Xs);
  532.            if (S > 0) then
  533.                 Dec(Ys);
  534.  
  535.            PutPixel(X+Xs-1, Y-Ys+1, GetColour);
  536.            PutPixel(X-Xs+1, Y-Ys+1, GetColour);
  537.            PutPixel(X+Ys-1, Y-Xs+1, GetColour);
  538.            PutPixel(X-Ys+1, Y-Xs+1, GetColour);
  539.            PutPixel(X+Xs-1, Y+Ys-1, GetColour);
  540.            PutPixel(X-Xs+1, Y+Ys-1, GetColour);
  541.            PutPixel(X+Ys-1, Y+Xs-1, GetColour);
  542.            PutPixel(X-Ys+1, Y+Xs-1, GetColour);
  543.      Until (Xs >= Ys);
  544. end;
  545.  
  546. Procedure InitPlayers;
  547. Var count: byte;
  548. Begin
  549.      For count:= 1 to MaxPlayers do
  550.          With PlayerRec[count] do
  551.               Begin
  552.               Warp(Count);
  553.  
  554.               PlayerMessage:='Player '+chr(48+Count)+' ready !';
  555.               MessageTime:=NormalMessageTime;
  556.  
  557.               ExplodeWidth:=0;
  558.               PlayerColour:=ColourTable[Count];
  559.  
  560.               PlayerWraps:=True;
  561.  
  562.               PlayerSpeed:=4;
  563.               NormalPlayerSpeed:=PlayerSpeed;
  564.  
  565.               SlowedDownTime:=0;
  566.               PlayerWait:=1;
  567.  
  568.               WaitCount:=15;
  569.               MaxWaitCount:=WaitCount;
  570.  
  571.               Thrusting:=False;
  572.  
  573.               InvulnerableTime:=MaxInvulnerableTime; { So if you warp into Paccy you
  574.                                                        can still get away }
  575.               BanzaiTime:=0;
  576.  
  577.               PlayerEnergy:=20;
  578.               MaxPlayerEnergy:=PlayerEnergy;
  579.               RechargeTime:=40;
  580.               RechargeLatch:=RechargeTime;
  581.               RechargeDeduction:=10;
  582.  
  583.               KeyReverseTime:=0;
  584.  
  585.               AssFiring:=False;
  586.               DisableTime:=0;
  587.  
  588.               AutoFire:=True;
  589.               FireKeyReleased:=true;
  590.               FireDelay:=3;
  591.               FireLatch:=FireDelay;
  592.  
  593.               CurrentLaserType:=NormalLaser;
  594.               CurrentLaserPower:=1;
  595.               CurrentLaserSpeed:=8;
  596.               CurrentMaxLaserTravel:=80;
  597.  
  598.               LaserDeduction:=1;
  599.  
  600.               LaserHurts:=False;
  601.               EnemyLaserHurts:=True;
  602.  
  603.               PlayerScore:=0;
  604.          End;
  605. End;
  606.  
  607.  
  608. {
  609. Flush laser array
  610. }
  611.  
  612. Procedure InitLasers;
  613. Var Count: byte;
  614. Begin
  615.      LasersFired:=0;
  616.      LastLaserIndex:=1;
  617.      For Count:=1 to MaxLasers do
  618.      With LaserRec[Count] do
  619.          LaserType:=LaserFree;
  620. End;
  621.  
  622. {$IFDEF BONUSES}
  623. Procedure InitBonuses;
  624. Var Count: byte;
  625. Begin
  626.      BonusesOnScreen:=0;
  627.      BonusString:='SEFRDIANTLWB?';      { Not explaining what this is for }
  628.  
  629.      For Count:= 1 to MaxBonuses do
  630.          With BonusRec[Count] do
  631.          Begin
  632.               BonusType:=0;
  633.          End;
  634. End;
  635. {$ENDIF}
  636.  
  637. Procedure SetUpPlayers;
  638. var Count: word;
  639.     keyhit: char;
  640.     PromptLatch: byte;
  641.     PromptTime: byte;
  642.     TextRefreshCount: byte;
  643.  
  644. Begin
  645.      For Count:=0 to 359 do
  646.          Begin
  647.          QCos[Count]:=Cos(Count * (PI/180));
  648.          QSin[Count]:=Sin(Count * (PI/180));
  649.      end;
  650.  
  651.      { Assign player colours }
  652.  
  653.      For Count:=1 to MaxPlayers do
  654.          ColourTable[Count]:=256-Count;
  655.  
  656.      Randomize;
  657.  
  658.      PlayersOn:=MaxPlayers;
  659.      PlayersAlive:=PlayersOn;
  660.  
  661.      InitPlayers;
  662.      InitLasers;
  663. {$IFDEF BONUSES}
  664.      InitBonuses;
  665. {$ENDIF}
  666.  
  667.  
  668.      {
  669.      Now draw the title screen
  670.      }
  671.  
  672.      PromptLatch:=50;
  673.      PromptTime:=PromptLatch;
  674.      TextRefreshCount:=0;
  675.  
  676.      SetPalette(254, 63,0,0);
  677.      SetPalette(255, 63,63,0);
  678.  
  679.      Repeat
  680.            BitMapCopy(titleBitmapSeg,titleBitmapOfs);
  681.  
  682.            SelectFont(6);
  683.  
  684.            TextXY(92,8,'SPACE LORDS 7½');
  685.  
  686.            SelectFont(1);
  687.            TextXY(32,70, 'PROGRAMMING BY : Scott Tunstall');
  688.  
  689.            if (TextRefreshCount < 4) Then
  690.               Begin
  691.               TextXY(32,96,  'VECTOR GFX  BY  : Scott Tunstall');
  692.               TextXY(32,112, 'PAC MAN     BY  : Namco (tm)');
  693.               TextXY(32,128, 'DIRTY WOMEN AT  : MarketGait');
  694.               end
  695.            else
  696.               Begin
  697.               SelectFont(Font8x16);
  698.               TextXY(48,96,  'SO RONNY NOW DO YOU BELIEVE');
  699.               TextXY(48,114, 'THAT I WROTE THIS PROGRAM ?');
  700.               SelectFont(Int43Font);
  701.               End;
  702.  
  703.  
  704.            Delay(1);
  705.            Dec(PromptTime);
  706.            If PromptTime=0 Then
  707.               Begin
  708.               PromptTime:=50;
  709.               Inc(TextRefreshCount);
  710.               Asm
  711.               AND BYTE PTR TextRefreshCount, $7
  712.               End;
  713.            End;
  714.  
  715.            If (PromptTime > 25) Then
  716.               Begin
  717.               TextXY(32,162,'PRESS SPACE TO BEGIN THE GAME !');
  718.            End;
  719.  
  720.            SelectFont(Font8x16);
  721.            TextXY(32,180,'Program  (C) 1995 Scott Tunstall.');
  722.  
  723.  
  724.            CopySourceBitmap ;
  725.  
  726.            if keypressed then
  727.               keyhit:=readkey;
  728.  
  729.      Until keyhit = ' ';
  730.  
  731. End;
  732.  
  733. Procedure DrawPlayerStuff;
  734. var PlayerCount: byte;
  735.     OriginX: integer;
  736.     OriginY: integer;
  737.     Angle: integer;
  738.     LineCount: byte;
  739.     CircCount: byte;
  740.     TempString: string[6];
  741.  
  742. Begin
  743.      UseFont(1);
  744.      For PlayerCount:=1 to PlayersOn do
  745.          With PlayerRec[PlayerCount] do
  746.               Begin
  747.  
  748.               Str(PlayerScore,TempString);
  749.               SetColour(PlayerColour);
  750.               OutTextXY(0,192- PlayerCount SHL 3,TempString);
  751.  
  752.               If MessageTime <>0 Then
  753.                  Begin
  754.                  Dec(MessageTime);
  755.  
  756. {$IFDEF FULLDISPLAY}
  757.                  TextXY(56,192-PlayerCount SHL 3,PlayerMessage);
  758.                  SetColour(PlayerColour);
  759. {$ELSE}
  760.                  OutTextXY(56,192-PlayerCount SHL 3,PlayerMessage);
  761. {$ENDIF}
  762.  
  763.               End;
  764.  
  765.               {
  766.               Time to draw the ship. I am quite pleased that this
  767.               routine is fairly fast.
  768.               }
  769.  
  770.  
  771.  
  772.               If (PlayerStatus And ShootAble)=ShootAble  Then
  773.                  Begin
  774.                  If (InvulnerableTime >10) Or
  775.                     (InvulnerableTime MOD 2 = 1) Then
  776.                     Circle(PlayerX,PlayerY,12);
  777.  
  778.                  If (BanzaiTime = 0) Or ((BanzaiTime MOD 8 )>3 ) Then
  779.                     Begin
  780.                     Angle:=PlayerAngle;
  781.  
  782.                     {
  783.                     Nose of ship is 8 pixels away from
  784.                     the start area at degree <Angle>
  785.                     }
  786.  
  787.                     OriginX:=PlayerX+ Round(QCos[Angle] * 8);
  788.                     OriginY:=PlayerY+ Round(QSin[Angle] * 8);
  789.  
  790.                     MoveTo(OriginX,OriginY);
  791.  
  792.                     Asm
  793.                     MOV AX,Angle
  794.                     ADD AX,135
  795.                     CMP AX,360
  796.                     JB @ThisAngleIsOK1
  797.                     SUB AX,360
  798.    @ThisAngleIsOK1:
  799.                     MOV Angle,AX
  800.                     End;
  801.  
  802.                     LineTo(PlayerX+ Round(QCos[Angle] * 8),
  803.                     PlayerY+ Round(QSin[Angle] * 8));
  804.                     ;
  805.  
  806.                     Asm
  807.                     MOV AX,Angle
  808.                     ADD AX,45
  809.                     CMP AX,360
  810.                     JB @ThisAngleIsOK2
  811.                     SUB AX,360
  812.    @ThisAngleIsOK2:
  813.                     MOV Angle,AX
  814.                     End;
  815.  
  816.                     LineTo(PlayerX+Round(QCos[Angle] * 2),
  817.                     PlayerY+Round(QSin[Angle] * 2));
  818.  
  819.                     Asm
  820.                     MOV AX,Angle
  821.                     ADD AX,45
  822.                     CMP AX,360
  823.                     JB @ThisAngleIsOK3
  824.                     SUB AX,360
  825.    @ThisAngleIsOK3:
  826.                     MOV Angle,AX
  827.                     End;
  828.  
  829.                     LineTo(PlayerX+Round(QCos[Angle] * 8),
  830.                     PlayerY+Round(QSin[Angle] * 8));
  831.  
  832.                     LineTo(OriginX,OriginY);
  833.  
  834.  
  835.  
  836.  
  837.    {$IFDEF FULLDISPLAY}
  838.  
  839.                     If Thrusting And (Random(2)=1) Then
  840.                        Begin
  841.                        SetColour(Random(255));
  842.  
  843.  
  844.                        Angle:=PlayerAngle;
  845.  
  846.                        Asm
  847.                        MOV AX,Angle  { I've tried the other way ! }
  848.                        ADD AX,150
  849.                        CMP AX,360
  850.                        JB @ThisAngleIsOK4
  851.                        SUB AX,360
  852.    @ThisAngleIsOK4:
  853.                        MOV Angle,AX
  854.                        End;
  855.  
  856.  
  857.                        MoveTo(PlayerX+Round(QCos[Angle]*5),
  858.                        PlayerY+Round(QSin[Angle]*5));
  859.  
  860.                        Asm
  861.                        MOV AX,Angle
  862.                        ADD AX,30
  863.                        CMP AX,360
  864.                        JB @ThisAngleIsOK5
  865.                        SUB AX,360
  866.    @ThisAngleIsOK5:
  867.                        MOV Angle,AX
  868.                        End;
  869.  
  870.  
  871.                        LineTo(PlayerX+Round(QCos[Angle]*8),
  872.                        PlayerY+Round(QSin[Angle]*8));
  873.  
  874.                        {Inc(Angle,30);
  875.  
  876.                        If Angle > 360 Then
  877.                           Dec(Angle,360);}
  878.  
  879.                        Asm
  880.                        MOV AX,Angle
  881.                        ADD AX,30
  882.                        CMP AX,360
  883.                        JB @ThisAngleIsOK6
  884.                        SUB AX,360
  885.    @ThisAngleIsOK6:
  886.                        MOV Angle,AX
  887.  
  888.                        End;
  889.  
  890.                        LineTo(PlayerX+Round(QCos[Angle]*5),PlayerY+Round(QSin[Angle]*5));
  891.  
  892.                     End;
  893.  
  894.    {$ENDIF}
  895.                     SetColour(PlayerColour);
  896.  
  897.                     OriginX:=PlayerX-12;
  898.                     OriginY:=PlayerY+12;
  899.  
  900.                     Line(OriginX,OriginY,OriginX + PlayerEnergy,OriginY);
  901.                     End;
  902.                  End
  903.               Else
  904.                   If (PlayerStatus = Exploding) Or (PlayerStatus = Warping) Then
  905.                      Begin
  906.                      For circcount:=0 to 40 do
  907.                          PutPixel(PlayerX+Round(QCos[circcount SHL 3]*ExplodeWidth),
  908.                          PlayerY+Round(QSin[circcount SHL 3]*ExplodeWidth),PlayerColour);
  909.  
  910.                   End;
  911.          End;
  912. End;
  913.  
  914. {
  915. Put the lasers on the screen.
  916. }
  917.  
  918.  
  919. Procedure DrawLasers;
  920. var LaserCount: byte;
  921. Begin
  922.      If LasersFired <>0 Then
  923.      For LaserCount:=1 to MaxLasers do
  924.          If LaserRec[LaserCount].LaserType <> LaserFree Then
  925.          With LaserRec[LaserCount] do
  926.          Begin
  927.          SetColour(LaserColour);
  928.          MoveTo(LaserX,LaserY);
  929.          LineRel(Round(QCos[LaserAngle]*LaserSize),
  930.          Round(QSin[LaserAngle]*LaserSize));
  931.          End;
  932.  
  933. End;
  934.  
  935.  
  936. {$IFDEF BONUSES}
  937.  
  938. Procedure DrawBonuses;
  939. var BonusCount: byte;
  940.  
  941. Begin
  942.      SetColour(255);
  943.      If BonusesOnScreen <>0 Then
  944.         For BonusCount:=1 to MaxBonuses do
  945.             With BonusRec[BonusCount] do
  946.             If BonusType <>0 Then
  947.                Begin
  948.                Circle(BonusX+4,BonusY+4,12);
  949.  
  950. {$IFDEF FULLDISPLAY}
  951.                UseFont(Font8x14);
  952.                TextXY(BonusX,BonusY,BonusString[BonusType]);
  953. {$ELSE}
  954.                OutTextXY(BonusX,BonusY,BonusString[BonusType]);
  955. {$ENDIF}
  956.                End;
  957.  
  958. End;
  959.  
  960. {$ENDIF}
  961.  
  962. Procedure CheckBounds(Var XPos,YPos:integer;
  963.                           ObjectWraps: boolean;
  964.                           Var DidWrap:boolean); Assembler;
  965.  
  966. Asm
  967.    CMP ObjectWraps,1
  968.  
  969.    JNE @ObjectDoesNotWrap
  970.  
  971.    MOV SI,RightBoundary
  972.    MOV DI,LeftBoundary
  973.    MOV CX,BottomBoundary
  974.    MOV DX,TopBoundary
  975.    JMP @LetsDoThisshit
  976.  
  977.  
  978. @ObjectDoesNotWrap:
  979.    MOV SI,LeftBoundary
  980.    MOV DI,RightBoundary
  981.    MOV CX,TopBoundary
  982.    MOV DX,BottomBoundary
  983.  
  984. @LetsDoThisshit:
  985.      XOR AL,AL
  986.  
  987.      LES BX,XPos
  988.      MOV BX,[ES:BX]
  989.  
  990.      CMP BX,LeftBoundary
  991.      JG @XPosMoreThanLeft
  992.  
  993.      LES DI,XPos
  994.      MOV [ES:DI],SI
  995.  
  996.      INC AL
  997.      JMP @NowTestVertical
  998.  
  999.  
  1000. @XPosMoreThanLeft:
  1001.      CMP BX,RightBoundary
  1002.      JL @NowTestVertical
  1003.  
  1004.      LES SI,Xpos
  1005.      MOV [ES:SI],DI
  1006.  
  1007.      INC AL
  1008.  
  1009.  
  1010.  
  1011.  
  1012. @NowTestVertical:
  1013.      LES BX,Ypos
  1014.      MOV BX,[ES:BX]
  1015.  
  1016.      CMP BX,TopBoundary
  1017.      JG @YPosMoreThanTop
  1018.  
  1019.      LES DI,Ypos
  1020.      MOV [ES:DI],CX
  1021.      MOV AL,1
  1022.      JMP @Finito
  1023.  
  1024. @YPosMoreThanTop:
  1025.      CMP BX,BottomBoundary
  1026.      JL @Finito
  1027.  
  1028.      LES DI,YPos
  1029.      MOV [ES:DI],DX
  1030.  
  1031.      MOV AL,1
  1032.  
  1033. @Finito:
  1034.      LES DI,DidWrap
  1035.      MOV [ES:DI],AL
  1036. End;
  1037.  
  1038.  
  1039. Procedure AddLaser(LaserToAdd: Laser);
  1040. Var VacantLaserNumber: byte;
  1041.     LaserCount: byte;
  1042.  
  1043. Begin
  1044.      If LaserRec[LastLaserIndex].LaserType = LaserFree Then
  1045.         VacantLaserNumber:=LastLaserIndex
  1046.      Else
  1047.          Begin
  1048.          VacantLaserNumber:=$FF;
  1049.          For LaserCount:=1 to MaxLasers do
  1050.              Begin
  1051.              If LaserRec[LaserCount].LaserType = LaserFree Then
  1052.                 Begin
  1053.                 VacantLaserNumber:=LaserCount;
  1054.                 LaserCount:=MaxLasers;
  1055.              End;
  1056.          End;
  1057.      End;
  1058.  
  1059.      If VacantLaserNumber <> $FF Then
  1060.         Begin
  1061.         Inc(LasersFired);
  1062.         LaserRec[VacantLaserNumber]:=LaserToAdd;
  1063.      End;
  1064. End;
  1065.  
  1066.  
  1067. Procedure DoFireRoutine(ShipNo:byte);
  1068. Var TAngle: word;
  1069. Begin
  1070.      If LasersFired <> MaxLasers Then
  1071.         With PlayerRec[ShipNo] do
  1072.         Begin
  1073.              TempLaser.LaserType:=CurrentLaserType;
  1074.              TempLaser.FiredBy:=ShipNo;
  1075.              If AssFiring Then
  1076.                 Begin
  1077.                 TempLaser.LaserX:=PlayerX-Round(QCos[PlayerAngle] * 6);
  1078.                 TempLaser.LaserY:=PlayerY-Round(QSin[PlayerAngle] * 6);
  1079.  
  1080.                 TAngle:=PlayerAngle+180;
  1081.  
  1082.                 Asm
  1083.                 MOV AX,TAngle
  1084.                 CMP AX,360
  1085.                 JB @NoReset
  1086.                 SUB AX,360
  1087. @NoReset:
  1088.                 MOV Tangle,AX
  1089.                 End;
  1090.  
  1091.                 TempLaser.LaserAngle:= TAngle;
  1092.                 End
  1093.              Else
  1094.                  Begin
  1095.                  Templaser.LaserX:=PlayerX+Round(QCos[PlayerAngle] * 6);
  1096.                  Templaser.LaserY:=PlayerY+Round(QSin[PlayerAngle] * 6);
  1097.                  Templaser.LaserAngle:= PlayerAngle;
  1098.              End;
  1099.  
  1100.              { Make sure you know who fired the laser }
  1101.  
  1102.              TempLaser.LaserColour:=PlayerColour;
  1103.  
  1104.              TempLaser.LaserPower:=CurrentLaserPower;
  1105.              TempLaser.LaserSize:= PlayerLaserSize;
  1106.              TempLaser.LaserSpeed:=CurrentLaserSpeed;
  1107.              TempLaser.MaxLaserTravel:=CurrentMaxLaserTravel;
  1108.  
  1109.              AddLaser(TempLaser);
  1110.  
  1111.              Dec(PlayerScore,DeductionForShooting);
  1112.              If PlayerScore < 0 Then PlayerScore:=0;
  1113.         End;
  1114. End;
  1115.  
  1116.  
  1117. Procedure AlterShip(ShipNo:byte;UpKey,DownKey,LeftKey,RightKey,FireKey:boolean);
  1118. Var DiscardedVar: boolean;
  1119.     TempKey: boolean;
  1120.  
  1121. Begin
  1122.        With PlayerRec[ShipNo] do
  1123.             Begin
  1124.  
  1125.             If UpKey Then
  1126.                Begin
  1127.                Thrusting:=True;
  1128.                If WaitCount > 1 Then
  1129.                   Dec(WaitCount);
  1130.                End
  1131.             Else
  1132.                 Begin
  1133.                 Thrusting:=False;
  1134.                 If WaitCount < MaxWaitCount Then
  1135.                    Inc(WaitCount)
  1136.                 Else
  1137.  
  1138.  
  1139.                     Begin
  1140.                     Dec(RechargeTime);
  1141.                     If (RechargeTime = 0) And
  1142.                     (PlayerEnergy < MaxPlayerEnergy) And
  1143.                     (PlayerScore >= RechargeDeduction) Then
  1144.  
  1145.                        Begin
  1146.                        RechargeTime:=RechargeLatch;
  1147.                        Inc(PlayerEnergy);
  1148.  
  1149.                        Dec(PlayerScore, RechargeDeduction);
  1150.                        End;
  1151.                     End;
  1152.                 End;
  1153.  
  1154.  
  1155.             If KeyReverseTime <>0 Then
  1156.                Begin
  1157.                TempKey:=LeftKey;
  1158.                LeftKey:=RightKey;
  1159.                RightKey:=TempKey;
  1160.             End;
  1161.  
  1162.  
  1163.             If LeftKey Then
  1164.             Begin
  1165.                  Dec(PlayerAngle,ShipTurnAngle);
  1166.                  If PlayerAngle <1 Then
  1167.                     Inc(PlayerAngle,360);
  1168.             End;
  1169.  
  1170.  
  1171.             If RightKey Then
  1172.             Begin
  1173.                  Inc(PlayerAngle,ShipTurnAngle);
  1174.                  If PlayerAngle > 359 Then
  1175.                     Dec(PlayerAngle,360);
  1176.             End;
  1177.  
  1178.             {
  1179.             Has the player held down the fire button.
  1180.             }
  1181.  
  1182.             If FireKey Then
  1183.                Begin
  1184.                If (DisableTime=0) Then
  1185.                   Begin
  1186.                   If AutoFire Then
  1187.                   Begin
  1188.  
  1189.                      If FireDelay = 0 Then
  1190.                         Begin
  1191.                         FireDelay:=FireLatch;
  1192.                         DoFireRoutine(ShipNo);
  1193.                         End
  1194.                      Else
  1195.  
  1196.                          Dec(FireDelay);
  1197.                   End
  1198.                   Else
  1199.                       If FireKeyReleased Then
  1200.                       Begin
  1201.                          FireKeyReleased:=False;
  1202.                          DoFireRoutine(ShipNo);
  1203.                       End;
  1204.                End;
  1205.             End
  1206.             Else
  1207.  
  1208.                 FireKeyReleased:=True;
  1209.  
  1210.  
  1211.  
  1212.             If WaitCount <> MaxWaitCount Then
  1213.                Begin
  1214.                Inc(PlayerWait);
  1215.                If PlayerWait >= WaitCount Then
  1216.                   Begin
  1217.                   PlayerWait:=0;
  1218.                   Inc(PlayerX, Round(Qcos[PlayerAngle]*PlayerSpeed));
  1219.                   Inc(PlayerY, Round(QSin[PlayerAngle]*PlayerSpeed));
  1220.  
  1221.  
  1222.                   CheckBounds(PlayerX,PlayerY,PlayerWraps,DiscardedVar);
  1223.                   End;
  1224.             End;
  1225.        End;
  1226.  
  1227. End;
  1228.  
  1229. Procedure UpDatePlayersSpin(PlayerNo:byte);
  1230. Var DiscardedVar: boolean;
  1231. Begin
  1232.      With PlayerRec[PlayerNo] do
  1233.      Begin
  1234.  
  1235.  
  1236.      Inc(PlayerAngle,ShipTurnAngle SHL 3);
  1237.      If PlayerAngle > 359 Then Dec(PlayerAngle,360);
  1238.  
  1239.  
  1240.      Inc(PlayerX, Round(Qcos[SpinAngle]*SpinSpeed));
  1241.      Inc(PlayerY, Round(QSin[SpinAngle]*SpinSpeed));
  1242.  
  1243.  
  1244.      CheckBounds(PlayerX,PlayerY,PlayerWraps,DiscardedVar);
  1245.      End;
  1246. End;
  1247.  
  1248. {$IFNDEF BONUSES}
  1249. Procedure UpDateBonusTimer(PlayerNo:byte);
  1250. Begin
  1251.      { Shields }
  1252.      With PlayerRec[PlayerNo] do
  1253.      If InvulnerableTime <>0  Then
  1254.         Begin
  1255.         Dec(InvulnerableTime);
  1256.         If InvulnerableTime = 0 Then
  1257.            Begin
  1258.            PlayerMessage:='SHIELDS DOWN!';
  1259.            MessageTime:=NormalMessageTIme;
  1260.            EnemyLaserHurts:=True;
  1261.         End;
  1262.      End;
  1263. End;
  1264.  
  1265. {$ELSE}
  1266.  
  1267. Procedure UpdateBonusTimers(PlayerNo:byte);
  1268. Begin
  1269.      With PlayerRec[PlayerNo] do
  1270.      Begin
  1271.  
  1272.      { Firing }
  1273.  
  1274.      If DisableTime <>0 Then
  1275.         Begin
  1276.         Dec(DisableTime);
  1277.         If DisableTime = 0 Then
  1278.            Begin
  1279.            PlayerMessage:='I CAN SHOOT AGAIN!';
  1280.            MessageTime:=NormalMessageTime;
  1281.         End;
  1282.      End;
  1283.  
  1284.      { Slothfullness }
  1285.  
  1286.      If SlowedDownTime <>0 Then
  1287.      Begin
  1288.           Dec(SlowedDownTime);
  1289.           If SlowedDownTime = 0 Then
  1290.              PlayerSpeed:=NormalPlayerSpeed;
  1291.      End;
  1292.  
  1293.      { Key reversing, i.e. press key for left and you go right }
  1294.  
  1295.      If KeyReverseTime <>0 Then
  1296.         Dec(KeyReverseTime);
  1297.  
  1298.      { Shields }
  1299.  
  1300.      If InvulnerableTime <>0  Then
  1301.         Begin
  1302.         Dec(InvulnerableTime);
  1303.         If InvulnerableTime = 0 Then
  1304.            Begin
  1305.            PlayerMessage:='SHIELDS DOWN!';
  1306.            MessageTime:=NormalMessageTIme;
  1307.            EnemyLaserHurts:=True;
  1308.         End;
  1309.      End;
  1310.  
  1311.      { Toody's special bonus }
  1312.  
  1313.      If BanzaiTime <> 0 Then
  1314.         Begin
  1315.         Dec(BanzaiTime);
  1316.         If BanzaiTime = 0 Then
  1317.            Begin
  1318.            PlayerMessage:='TOODY''S POWER GONE!';
  1319.            MessageTime:=NormalMessageTime;
  1320.         End;
  1321.      End;
  1322.  
  1323.      End;
  1324. End;
  1325.  
  1326. {$ENDIF}
  1327.  
  1328. {
  1329. You have to check the player's status byte to determine whether
  1330. or not he's spinning, frozen, etc.
  1331. }
  1332.  
  1333.  
  1334. Procedure CheckPlayerStatusByte(PlayerNo:byte);
  1335. Begin
  1336.      With PlayerRec[PlayerNo] Do
  1337.      Begin
  1338.      {
  1339.      Now service the PlayerStatus bits
  1340.      }
  1341.  
  1342.      If (PlayerStatus And Frozen)=Frozen Then
  1343.         Begin
  1344.         If FrozenTime > 0 Then
  1345.            Dec(FrozenTime)
  1346.         Else
  1347.             PlayerStatus:=PlayerStatus And (255-Frozen);
  1348.      End;
  1349.  
  1350.  
  1351.      If (PlayerStatus And Spinning)=Spinning Then
  1352.         Begin
  1353.  
  1354.         Dec(SpinCount);
  1355.         If SpinCount <>0 Then
  1356.            UpdatePlayersSpin(PlayerNo)
  1357.         Else
  1358.             Begin
  1359.  
  1360.             PlayerStatus:= ShootAble;
  1361.             WaitCount:=MaxWaitCount;
  1362.             End;
  1363.         End
  1364.      Else
  1365.          If PlayerStatus = Exploding Then
  1366.             Begin
  1367.  
  1368.             Inc(ExplodeWidth,5);
  1369.  
  1370.             If ExplodeWidth >= MaxExplodeWidth Then
  1371.                Begin
  1372.                PlayerStatus:= Dead;
  1373.                Dec(PlayersAlive);
  1374.                End;
  1375.             End
  1376.          Else
  1377.              If PlayerStatus = Warping Then
  1378.                 Begin
  1379.                 Dec(ExplodeWidth,5);
  1380.                 If ExplodeWidth <=5 Then
  1381.                    PlayerStatus:=ShootAble;
  1382.              End;
  1383.  
  1384.      End;
  1385. End;
  1386.  
  1387. {
  1388. Update the player's ships.
  1389.  
  1390. PlayerStatus is a combination of BIT FLAGS which indicate to the
  1391. program the current player status. Doh!
  1392.  
  1393. If bit 0 of PlayerStatus is set then the player is still ShootAble. (i.e. Alive)
  1394. If bit 1 of PlayerStatus is set then the player is Warping.
  1395. If bit 2 of PlayerStatus is set then the player is Exploding.
  1396. If bit 3 of PlayerStatus is set then the Player is Spinning.
  1397. If bit 4 of PlayerStatus is set the player is Frozen.
  1398.  
  1399. Bits 5 - 7 are undefined and should stay that way for now.
  1400. }
  1401.  
  1402. Procedure MoveShips;
  1403. Var PlayerCount: byte;
  1404. Begin
  1405.      For PlayerCount:=1 to PlayersOn do
  1406.          With PlayerRec[PlayerCount] do
  1407.          If (PlayerStatus = ShootAble) Then
  1408.             Begin
  1409.             Case PlayerCount Of
  1410.  
  1411.             1: AlterShip(1,keydown[2],keydown[15],keydown[30],keydown[45],keydown[42]);
  1412.             2: AlterShip(2,keydown[24],keydown[38],keydown[39],keydown[40],keydown[52]);
  1413.             3: AlterShip(3,keydown[71],keydown[76],keydown[73],keydown[74],keydown[81]);
  1414.  
  1415.             End;
  1416.  
  1417. {$IFNDEF BONUSES}
  1418.             UpdateBonusTimer(PlayerCount);
  1419. {$ELSE}
  1420.             UpdateBonusTimers(PlayerCount);
  1421. {$ENDIF}
  1422.             End
  1423.          Else
  1424.              CheckPlayerStatusByte(PlayerCount);
  1425. End;
  1426.  
  1427. {
  1428. O.K. You've got to update the lasers (and special weapons later
  1429. on, perhaps)
  1430.  
  1431. }
  1432.  
  1433. Procedure MoveLasers;
  1434. var playercount: byte;
  1435.     LaserCount: byte;
  1436.     ItWrapped: boolean;
  1437.  
  1438. Begin
  1439.      If LasersFired <>0 Then
  1440.         Begin
  1441.         For LaserCount:=1 to MaxLasers do
  1442.             With LaserRec[LaserCount] do
  1443.             Begin
  1444.  
  1445.             If LaserType<>LaserFree Then
  1446.                Begin
  1447.  
  1448.                Inc(LaserTravel);
  1449.  
  1450.                If LaserTravel < MaxLaserTravel Then
  1451.                   Begin
  1452.  
  1453.                   Inc(LaserX, Round(Qcos[LaserAngle]*LaserSpeed));
  1454.                   Inc(LaserY, Round(QSin[LaserAngle]*LaserSpeed));
  1455.  
  1456.  
  1457.                   CheckBounds(LaserX,LaserY, LaserType = LaserWraps,ItWrapped);
  1458.  
  1459.  
  1460.                   If ItWrapped Then
  1461.                      Begin
  1462.                      Case LaserType of
  1463.                      NormalLaser:   Begin
  1464.                                     LaserType:=LaserFree;
  1465.                                     LastLaserIndex:=LaserCount;
  1466.                                     Dec(LasersFired);
  1467.                                     End;
  1468.  
  1469.                      LaserRebound:  LaserAngle:=Random(359);
  1470.                      End;
  1471.                      End;
  1472.                   End
  1473.                Else
  1474.  
  1475.                    Begin
  1476.                    LaserType:=LaserFree;
  1477.                    Dec(LasersFired);
  1478.  
  1479.  
  1480.  
  1481.                    LastLaserIndex:=LaserCount;
  1482.  
  1483.                    End;
  1484.                End;
  1485.             End;
  1486.         End;
  1487. End;
  1488.  
  1489. {$IFDEF BONUSES}
  1490.  
  1491.  
  1492. {
  1493. The Bonuses are not player controlled (of course) so therefore
  1494. the MoveBonuses routine should initiate some bonuses as well
  1495. as move them.
  1496.  
  1497. How will the CPU know when to initiate bonuses? Well as you
  1498. know, it can't so It'll have to be a purely random thingie.
  1499. }
  1500.  
  1501. Procedure MoveBonuses;
  1502. Var BonusCount: byte;
  1503.     SearchCount: byte;
  1504.     BonusDidWrap: boolean;
  1505.  
  1506. Begin
  1507.      If BonusesOnScreen <>0 Then
  1508.         For BonusCount:=1 to MaxBonuses do
  1509.         With BonusRec[BonusCount] do
  1510.              If BonusType <>0 Then
  1511.              Begin
  1512.              Inc(BonusX,BonusXIncrement);
  1513.              Inc(BonusY,BonusYIncrement);
  1514.              CheckBounds(BonusX,BonusY,true,BonusDidWrap);
  1515.  
  1516.              End;
  1517.  
  1518.      {
  1519.      Of course, some bonuses just have to be initialised as
  1520.      well !
  1521.      }
  1522.  
  1523.      If (BonusesOnScreen <= MaxBonuses) And (Random(80)=40) Then
  1524.         Begin
  1525.         SearchCount:=1;
  1526.         Repeat
  1527.               With BonusRec[SearchCount] do
  1528.               If BonusType = 0 Then
  1529.                    Begin
  1530.                    Inc(BonusesOnScreen);
  1531.  
  1532.                    BonusType:=1+(Random(NumberOfBonuses));
  1533.  
  1534.                    BonusX:=Random(319);
  1535.  
  1536.                    Case Random(3) of
  1537.                    0..1: BonusY:=-1;
  1538.                    2..3: BonusY:=200;
  1539.                    End;
  1540.  
  1541.                    Case Random(3) of
  1542.                    0..1: BonusXIncrement:=-1;
  1543.                    2..3: BonusXIncrement:=1;
  1544.                    End;
  1545.  
  1546.                    Case Random(3) of
  1547.                    0..1: BonusYIncrement:=-1;
  1548.                    2..3: BonusYIncrement:=1;
  1549.                    End;
  1550.  
  1551.                    SearchCount:=MaxBonuses;
  1552.               End;
  1553.  
  1554.         Inc(SearchCount);
  1555.  
  1556.         Until SearchCount > MaxBonuses;
  1557.      End;
  1558.  
  1559. End;
  1560.  
  1561. {$ENDIF}
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572. Function Collision(X1,Y1,X2,Y2:integer;DistX,DistY:word): boolean; {Assembler;}
  1573. Begin
  1574.      Collision:=(Abs(X2-X1) < DistX) And (Abs(Y2-Y1) < DistY)
  1575. End;
  1576.  
  1577. {===================================================================
  1578.  
  1579. Guess what this routine does ?
  1580.  
  1581. }
  1582.  
  1583.  
  1584. Procedure UpdatePlayerScore(PlayerNo: byte; HowManyPoints: integer);
  1585. Begin
  1586.      With PlayerRec[PlayerNo] do
  1587.      Begin
  1588.      Inc(PlayerScore,HowManyPoints);
  1589.      If PlayerScore > $7FFFFFFF Then
  1590.         PlayerScore := $7FFFFFFF;
  1591.      End;
  1592. End;
  1593.  
  1594. {=====================================================
  1595.  
  1596. I'm gonna have to optimize this one day.. For now tho'
  1597. I'll leave it as it is so that the B.Sc chaps can suss
  1598. what's happening..
  1599. }
  1600.  
  1601. Procedure DoPlayerToLaser;
  1602. Var PlayerCount: byte;
  1603.     LaserCount: byte;
  1604.     Object1X: integer;
  1605.     Object2X: integer;
  1606.     Object1Y: integer;
  1607.     Object2Y: integer;
  1608.  
  1609.     TempLaserPower: byte;
  1610.     PersonWhoShot: byte;
  1611.  
  1612. Begin
  1613.      If LasersFired <>0 Then
  1614.         For PlayerCount:=1 to PlayersOn do
  1615.             With PlayerRec[PlayerCount] do
  1616.             If ((PlayerStatus AND Shootable)<>0) Then
  1617.                Begin
  1618.                Object2X:=PlayerX;
  1619.                Object2Y:=PlayerY;
  1620.  
  1621.  
  1622.                For LaserCount:=1 to MaxLasers do
  1623.                If (LaserRec[LaserCount].LaserType <> LaserFree) Then
  1624.                   Begin
  1625.                   With LaserRec[LaserCount] do
  1626.                        Begin
  1627.                        Object1X:=LaserX;
  1628.                        Object1Y:=LaserY;
  1629.                   End;
  1630.  
  1631.                   If Collision( Object1X,Object1Y,
  1632.                                 Object2X,Object2Y,8,8) Then
  1633.                      Begin
  1634.                      PersonWhoShot:=LaserRec[LaserCount].FiredBy;
  1635.  
  1636.                      With PlayerRec[PersonWhoShot] do
  1637.                           Begin
  1638.                           Inc(PlayerScore,PointsForShooting);
  1639.                           If Playerscore > $7FFFFF Then
  1640.                              PlayerScore:= $7fffff;
  1641.                      End;
  1642.  
  1643.                      {
  1644.                      Player has been hit so make the missile
  1645.                      whack into the ships side and disappear
  1646.                      }
  1647.  
  1648.  
  1649.                      With PlayerRec[PlayerCount] do
  1650.                           If (InvulnerableTime <>0) Then
  1651.                              LaserRec[LaserCount].LaserAngle:=Random(359)
  1652.                           Else
  1653.                               Begin
  1654.                               Dec(LasersFired);
  1655.                               LaserRec[LaserCount].LaserType:=LaserFree;
  1656.                               TempLaserPower:=LaserRec[LaserCount].LaserPower;
  1657.  
  1658.                               If LaserRec[LaserCount].Firedby <> PlayerCount Then
  1659.                                  Begin
  1660.                                  Dec(PlayerEnergy,TempLaserPower);
  1661.                                  If PlayerEnergy <= 0 Then
  1662.                                     Begin
  1663.                                     PlayerStatus:=Exploding;
  1664.                                     ExplodeWidth:=0;
  1665.                                  End;
  1666.                               End;
  1667.                           End;
  1668.                      End;
  1669.                  End;
  1670.      End;
  1671. End;
  1672.  
  1673. {==========================================================
  1674.  
  1675. Guess what this does ?
  1676.  
  1677. }
  1678.  
  1679. Procedure SpinPlayer( PlayerBumped, PlayerWhoBumped: byte);
  1680. Var SpeedVar: byte;
  1681.     Ratio: byte;
  1682.  
  1683. begin
  1684.      With PlayerRec[PlayerBumped] do
  1685.         Begin
  1686.         PlayerStatus:=PlayerStatus OR Spinning;
  1687.  
  1688.         SpeedVar := PlayerRec[PlayerWhoBumped].WaitCount;
  1689.         Ratio    := PlayerRec[PlayerWhoBumped].MaxWaitCount - SpeedVar;
  1690.  
  1691.         WaitCount:=SpeedVar;
  1692.  
  1693.         SpinAngle:=PlayerRec[PlayerWhoBumped].PlayerAngle;
  1694.         SpinSpeed:= (Ratio SHR 2)+4;
  1695.         SpinCount:= (Ratio SHL 1)+4;
  1696.  
  1697.         UpDatePlayersSpin(PlayerBumped);
  1698.      End
  1699. End;
  1700.  
  1701. {
  1702.  
  1703. Check if two players did bump
  1704. }
  1705.  
  1706.  
  1707. {$IFDEF BUMPING }
  1708.  
  1709.  
  1710. Procedure CheckBump(PlayerCount1, PlayerCount2 : byte);
  1711. var
  1712.     PlayerSpeed1: byte;
  1713.     PlayerSpeed2: byte;
  1714.  
  1715. Begin
  1716.  
  1717.      If (PlayerRec[PlayerCount1].PlayerStatus = Exploding)
  1718.      Or (PlayerRec[PlayerCount2].PlayerStatus = Exploding) Then Exit;
  1719.  
  1720.  
  1721.      If (PlayerRec[PlayerCount1].BanzaiTime <>0) And
  1722.      (PlayerRec[PlayerCount2].InvulnerableTime = 0) Then
  1723.         With PlayerRec[PlayerCount2] do
  1724.            Begin
  1725.            PlayerStatus:=Exploding;
  1726.            ExplodeWidth:=0;
  1727.            Message:='AARGH etc. etc. !!';
  1728.            MessageTime:=NormalMessageTime;
  1729.            End
  1730.         Else
  1731.             Begin
  1732.             PlayerSpeed1:= PlayerRec[PlayerCount1].WaitCount;
  1733.             PlayerSpeed2:= PlayerRec[PlayerCount2].WaitCount;
  1734.  
  1735.             If (PlayerSpeed2 <= PlayerSpeed1) Then
  1736.                SpinPlayer(PlayerCount1,PlayerCount2)
  1737.             Else
  1738.                 UpdatePlayerScore(PlayerCount1,PointsForBumping);
  1739.             End;
  1740. End;
  1741.  
  1742.  
  1743.  
  1744. {$ENDIF}
  1745.  
  1746. {$IFDEF BUMPING}
  1747.  
  1748. Procedure DoPlayerToPlayer;
  1749. Var PlayerCount1: byte;
  1750.     PlayerCount2: byte;
  1751.     Object1X: integer;
  1752.     Object2X: integer;
  1753.     Object1Y: integer;
  1754.     Object2Y: integer;
  1755.  
  1756.  
  1757. Begin
  1758.      For PlayerCount1:=1 to PlayersOn do
  1759.          If (PlayerRec[PlayerCount1].PlayerStatus AND Shootable =
  1760.          ShootAble) Then
  1761.             Begin
  1762.             With PlayerRec[PlayerCount1] do
  1763.                  Begin
  1764.                  Object1X:=PlayerX;
  1765.                  Object1Y:=PlayerY;
  1766.             End;
  1767.  
  1768.  
  1769.  
  1770.             {
  1771.             Check if the two ships have bumped into each other.
  1772.             Not too keen on what I wrote for this part but it works.
  1773.             As I said when me B.Sc is finished this part will be
  1774.             upgraded.
  1775.             }
  1776.  
  1777.  
  1778.             For PlayerCount2:=1 to PlayersOn do
  1779.                 If (PlayerRec[PlayerCount2].PlayerStatus And
  1780.                 Shootable = Shootable) And
  1781.                    (PlayerCount1 <> PlayerCount2) Then
  1782.                    Begin
  1783.                    {
  1784.                    Check if a collision has occurred.
  1785.                    }
  1786.  
  1787.                    With PlayerRec[PlayerCount2] do
  1788.                         Begin
  1789.                         Object2X:=PlayerX;
  1790.                         Object2Y:=PlayerY;
  1791.                    End;
  1792.  
  1793.                    {
  1794.                    Bumping?
  1795.                    }
  1796.  
  1797.                    If Collision(Object1X,Object1Y,Object2X,Object2Y,12,12)
  1798.                    Then
  1799.                       Begin
  1800.                       CheckBump(PlayerCount1, PlayerCount2);
  1801.                       CheckBump(PlayerCount2, PlayerCount1);
  1802.                    End;
  1803.                 End;
  1804.          End;
  1805. End;
  1806.  
  1807. {$ENDIF}
  1808.  
  1809. Procedure Warp(PlayerNo:byte);
  1810. Begin
  1811.      With PlayerRec[PlayerNo] do
  1812.      Begin
  1813.           PlayerStatus:=Warping;
  1814.           ExplodeWidth:=MaxExplodeWidth;
  1815.           PlayerAngle:= Random(359);
  1816.           PlayerX:=Random(319);
  1817.           PlayerY:=Random(199);
  1818.      End;
  1819. End;
  1820.  
  1821. {$IFDEF BONUSES}
  1822.  
  1823. Procedure DoPlayerToBonuses;
  1824. Var PlayerCount: byte;
  1825.     BonusCount: byte;
  1826.     OtherCount: byte;
  1827.     Object1X: integer;
  1828.     Object2X: integer;
  1829.     Object1Y: integer;
  1830.     Object2Y: integer;
  1831.  
  1832.  
  1833.  
  1834.  
  1835. Begin
  1836.      For PlayerCount:=1 to PlayersOn do
  1837.          If (PlayerRec[PlayerCount].PlayerStatus And Shootable) = Shootable
  1838.             Then Begin
  1839.  
  1840.             With PlayerRec[PlayerCount] do
  1841.             Begin
  1842.                  Object1X:=PlayerX;
  1843.                  Object1Y:=PlayerY;
  1844.             End;
  1845.  
  1846.             For BonusCount:=1 to MaxBonuses do
  1847.  
  1848.                 If (BonusRec[BonusCount].BonusType <>0 ) Then
  1849.                    Begin
  1850.  
  1851.                    With BonusRec[BonusCount] do
  1852.                         Begin
  1853.                         Object2X:=BonusX;
  1854.                         Object2Y:=BonusY;
  1855.                    End;
  1856.  
  1857.  
  1858.                    If collision( Object1X,Object1Y,
  1859.                                  Object2X,Object2Y,12,12) Then
  1860.  
  1861.                    With BonusRec[BonusCount] do
  1862.                    Begin
  1863.  
  1864.                         If BonusType = UnknownBonus Then
  1865.                            BonusType:= Random(NumberOfBonuses-2)+1;
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.                         Case BonusType Of
  1872.                         SlowDownBonus: begin
  1873.                                        With PlayerRec[PlayerCount] do
  1874.                                             Begin
  1875.                                             Inc(PlayerScore,SlowDownBonusPointsValue);
  1876. {$IFDEF MESSAGES}
  1877.                                             PlayerMessage:='PICKED UP A SLOWDOWN BONUS !';
  1878.                                             MessageTime:=NormalMessageTime;
  1879. {$ENDIF}
  1880.                                         End;
  1881.  
  1882.                                         For OtherCount:=1 to PlayersOn do
  1883.                                         If OtherCount <> PlayerCount Then
  1884.                                             With PlayerRec[OtherCount] do
  1885.                                                  Begin
  1886.                                                  If PlayerSpeed <>SlowestPlayerSpeed Then
  1887.                                                     Dec(PlayerSpeed);
  1888.  
  1889.                                                  Inc(SlowedDownTime,MaxSlowedDownTime);
  1890.                                             End;
  1891.                                         End;
  1892.  
  1893.  
  1894.                    EnergyBonus: With PlayerRec[PlayerCount] do
  1895.                                 Begin
  1896.                                 Inc(PlayerScore,EnergyBonusPointsValue);
  1897.                                 Inc(PlayerEnergy,EnergyIncrement);
  1898.  
  1899.                                 If PlayerEnergy >MaxPlayerEnergy Then
  1900.                                    Begin
  1901.                                    PlayerEnergy:=MaxPlayerEnergy;
  1902. {$IFDEF MESSAGES}
  1903.                                    PlayerMessage:='I DIDN''T NEED THE ENERGY !';
  1904.                                    MessageTime:=NormalMessageTime;
  1905. {$ENDIF}
  1906. {$IFDEF MESSAGES}
  1907.                                    End
  1908.                                 Else
  1909.                                     If PlayerEnergy <= EnergyIncrement Then
  1910.                                        Begin
  1911.                                        PlayerMessage:='ENERGY JUST IN TIME, TOO !';
  1912.                                        MessageTime:=NormalMessageTime;
  1913.                                        End
  1914.                                     Else
  1915.                                         Begin
  1916.                                         PlayerMessage:='PICKED UP AN ENERGY BONUS !';
  1917.                                         messageTime:=NormalMessageTime;
  1918.                                     End;
  1919.  
  1920. {$ENDIF}
  1921.                                 End;
  1922.  
  1923.  
  1924.                    FreezeBonus: Begin
  1925.                                 With PlayerRec[PlayerCount] do
  1926.                                      Begin
  1927.                                      Inc(PlayerScore,FreezeBonusPointsValue);
  1928. {$IFDEF MESSAGES}
  1929.                                      PlayerMessage:='PICKED UP A FREEZE BONUS !';
  1930.                                      MessageTime:=NormalMessageTime;
  1931. {$ENDIF}
  1932.                                 End;
  1933.  
  1934.                                 For OtherCount:=1 to PlayersOn do
  1935.                                     If OtherCount <> PlayerCount Then
  1936.                                     With PlayerRec[OtherCount] do
  1937.                                     Begin
  1938.                                     PlayerStatus:=PlayerStatus OR Frozen;
  1939.                                     Inc(FrozenTime,MaxFrozenTime);
  1940.                                     WaitCount:=MaxWaitCount;
  1941.                                 End;
  1942.                                 End;
  1943.  
  1944.  
  1945.                    ReverseBonus: Begin
  1946.                                  With PlayerRec[PlayerCount] do
  1947.                                  Begin
  1948.                                       Inc(PlayerScore,ReverseBonusPointsValue);
  1949. {$IFDEF MESSAGES}
  1950.                                       PlayerMessage:='PICKED UP A REVERSE BONUS !';
  1951.                                       MessageTime:=NormalMessageTime;
  1952. {$ENDIF}
  1953.                                  End;
  1954.  
  1955.                                  For OtherCount:=1 to PlayersOn do
  1956.                                     If OtherCount <> PlayerCount Then
  1957.                                     With PlayerRec[OtherCount] do
  1958.                                          Begin
  1959.                                          Inc(KeyReverseTime,MaxKeyReverseTime);
  1960.                                          PlayerMessage:='OH NO! KEYS ARE REVERSED !';
  1961.                                          MessageTime:=NormalMessageTime;
  1962.                                     End;
  1963.                                  End;
  1964.  
  1965.  
  1966.                    DisableBonus: Begin
  1967.                                  With PlayerRec[PlayerCount] do
  1968.                                       Begin
  1969.                                       Inc(PlayerScore,DisableBonusPointsValue);
  1970. {$IFDEF MESSAGES}
  1971.                                       PlayerMessage:='PICKED UP A DISABLE BONUS !';
  1972.                                       MessageTime:=NormalMessageTime;
  1973. {$ENDIF}
  1974.                                  End;
  1975.  
  1976.                                  For OtherCount:=1 to PlayersOn do
  1977.                                  If OtherCount <> PlayerCount Then
  1978.                                     Inc(PlayerRec[OtherCount].DisableTime,MaxDisableTime);
  1979.                                  End;
  1980.  
  1981.  
  1982.                    InvulnerabilityBonus: Begin
  1983.                                          With PlayerRec[PlayerCount] do
  1984.                                               Begin
  1985.                                               EnemyLaserHurts:=False;
  1986.                                               InvulnerableTime:=MaxInvulnerableTime;
  1987.  
  1988.                                               Inc(PlayerScore,InvulnerabilityBonusPointsValue);
  1989. {$IFDEF MESSAGES}
  1990.                                               PlayerMessage:='YEAH! I AM INVULNERABLE !';
  1991.                                               MessageTime:=NormalMessageTime;
  1992. {$ENDIF}
  1993.                                          End;
  1994.                                          End;
  1995.  
  1996.  
  1997.                    AssFiringBonus:  Begin
  1998.                                      With PlayerRec[PlayerCount] do
  1999.                                           Begin
  2000.                                           Inc(PlayerScore,AssFiringBonusPointsValue);
  2001. {$IFDEF MESSAGES}
  2002.                                           PlayerMessage:='PICKED UP AN Ass FIRING BONUS !';
  2003.                                           MessageTime:=NormalMessageTime;
  2004. {$ENDIF}
  2005.                                      End;
  2006.  
  2007.                                      For OtherCount:=1 to PlayersOn do
  2008.                                          If OtherCount <> PlayerCount Then
  2009.                                             With PlayerRec[OtherCount] do
  2010.                                             Begin
  2011.                                             AssFiring:=True;
  2012.                                          End;
  2013.                                      End;
  2014.  
  2015.  
  2016.                    NormalBonus:    Begin
  2017.                                    With PlayerRec[Playercount] do
  2018.                                    Begin
  2019.                                         DisableTime:=1;
  2020.                                         KeyReverseTime:=1;
  2021.                                         SlowedDownTime:=1;
  2022.                                         PlayerSpeed:=NormalPlayerSpeed;
  2023.                                         CurrentLaserType:=NormalLaser;
  2024.                                         AssFiring:=False;
  2025.  
  2026.                                         Inc(PlayerScore,NormalBonusPointsValue);
  2027. {$IFDEF MESSAGES}
  2028.                                         PlayerMessage:='PICKED UP A NORMALITY BONUS.';
  2029.                                         MessageTime:=NormalMessageTime;
  2030. {$ENDIF}
  2031.                                    End;
  2032.                                    End;
  2033.  
  2034.  
  2035.                    ToodysBonus:    Begin
  2036.                                    With PlayerRec[PlayerCount] do
  2037.                                         begin
  2038.                                         Inc(BanzaiTime,MaxBanzaiTime);
  2039.  
  2040.                                         Inc(PlayerScore,ToodysBonusPointsValue);
  2041. {$IFDEF MESSAGES}
  2042.                                         PlayerMessage:='BANZAI THE OTHER PLAYERS !';
  2043.                                         MessageTime:=MaxBanzaiTime;
  2044. {$ENDIF}
  2045.                                         End;
  2046.  
  2047.                                    For OtherCount:=1 to PlayersOn do
  2048.                                    If OtherCount <> PlayerCount Then
  2049.                                        With PlayerRec[OtherCount] do
  2050.                                        Begin
  2051. {$IFDEF MESSAGES}
  2052.                                        PlayerMessage:='DO NOT BUMP PLAYER '+chr(48 + PlayerCount)+' !';
  2053.                                        MessageTime:=MaxBanzaiTime;
  2054. {$ENDIF}
  2055.                                        End
  2056.                                    End;
  2057.  
  2058.  
  2059.                    LaserBonus:     Begin
  2060.                                    With PlayerRec[PlayerCount] do
  2061.                                    If CurrentLaserPower < MaxLaserPower Then
  2062.                                       Begin
  2063.                                       Inc(CurrentlaserPower);
  2064.  
  2065.                                       Inc(PlayerScore,LaserBonusPointsValue);
  2066. {$IFDEF MESSAGES}
  2067.                                       PlayerMessage:='LASERS ENHANCED !';
  2068.                                       MessageTime:=NormalMessageTime;
  2069. {$ENDIF}
  2070.                                       End
  2071.                                     Else
  2072.                                         Begin
  2073.                                         PlayerMessage:='WRAP AROUND LASERS !';
  2074.                                         CurrentLaserType:=LaserWraps;
  2075.                                         MessageTime:=NormalMessageTime;
  2076.                                     End;
  2077.                                    End;
  2078.  
  2079.                    WarpBonus:      With PlayerRec[PlayerCount] do
  2080.                                    Begin
  2081.                                         Warp(PlayerCount);
  2082.  
  2083.                                         Inc(PlayerScore,WarpBonusPointsValue);
  2084.  
  2085. {$IFDEF MESSAGES}
  2086.                                         PlayerMessage:='WARPING !';
  2087.                                         MessageTime:=NormalMessageTime;
  2088. {$ENDIF}
  2089.                                    End;
  2090.  
  2091.  
  2092.             BounceLaserBonus:      With PlayerRec[PlayerCount] do
  2093.                                    Begin
  2094.                                         CurrentLaserType:= LaserRebound;
  2095. {$IFDEF MESSAGES}
  2096.                                         PlayerMessage:='OOH! BOUNCY LASERS!';
  2097.                                         MessageTime:=NormalMessageTime;
  2098. {$ENDIF}
  2099.                                    End;
  2100.                    End;
  2101.  
  2102.  
  2103.                    { Indicate bonus has been taken
  2104.                    }
  2105.  
  2106.  
  2107.                    BonusRec[BonusCount].BonusType:=0;
  2108.                    Dec(BonusesOnScreen);
  2109.  
  2110.  
  2111.                 End;
  2112.          End;
  2113.      End;
  2114. End;
  2115. {$ENDIF}
  2116.  
  2117. Procedure DoCollisions;
  2118. Begin
  2119.  
  2120.      DoPlayerToLaser;
  2121.  
  2122. {$IFDEF BUMPING}
  2123.      DoPlayerToPlayer;
  2124. {$ENDIF}
  2125.  
  2126. {$IFDEF BONUSES}
  2127.      DoPlayerToBonuses;
  2128. {$ENDIF}
  2129. End;
  2130.  
  2131. Begin
  2132.      LoadGraphics;
  2133.      If (PlanetSeg <>0) And (titleBitmapSeg<>0)
  2134.      And (EmporerSeg<>0) And (ScratchSeg<>0) Then
  2135.         Begin
  2136.  
  2137.  
  2138.         Repeat
  2139.  
  2140.               InitVGAMode;
  2141.               SetAllPalette(titleBitmapPalette);
  2142.  
  2143.               SetUpPlayers;
  2144.  
  2145.               SetAllPalette(DestroyerPalette);
  2146.               SetPalette(253,63,63,63);
  2147.               SetPalette(254,63,0,0);
  2148.               SetPalette(255,63,63,0);
  2149.  
  2150.               HookKeyboardInt;
  2151.  
  2152.  
  2153.               SelectFont(1);
  2154.  
  2155.               Repeat
  2156.                     BitmapCopy(PlanetSeg,PlanetOfs);
  2157.                     DrawPlayerStuff;
  2158.                     DrawLasers;
  2159.  
  2160. {$IFDEF BONUSES}
  2161.                     DrawBonuses;
  2162. {$ENDIF}
  2163.  
  2164.                     Vwait(1);
  2165.                     CopySourceBitmap ;
  2166.  
  2167.  
  2168.                     MoveShips;
  2169.                     MoveLasers;
  2170.  
  2171. {$IFDEF BONUSES}
  2172.                     MoveBonuses;
  2173. {$ENDIF}
  2174.  
  2175.                     DoCollisions;
  2176.  
  2177.                     delay(1);
  2178.  
  2179.               Until (keydown[1]) or (PlayersAlive <= 1);
  2180.  
  2181.  
  2182.               { back to normal crap DOS key reading }
  2183.  
  2184.               UnHookKeyboardInt;
  2185.  
  2186.               If PlayersAlive <= 1 Then
  2187.                  Begin
  2188.  
  2189.                  Memw[$0040:$1a]:=Memw[$0040:$1c];
  2190.  
  2191.                  SetAllPalette(EmporerPalette);
  2192.  
  2193.                  BitMapCopy(EmporerSeg,EmporerOfs);
  2194.                  SelectFont(6);
  2195.  
  2196.                  SetColour(255);
  2197.  
  2198.                  {
  2199.                  El snido messago (Adjust to suit your peer group)
  2200.                  }
  2201.  
  2202.                  Case Random(20) of
  2203.                  0: Message:='Even Paul Langa has scored more !';
  2204.                  1: Message:='Stop drinking and you''ll shoot better !';
  2205.                  2: Message:='Next time, press the fire button !';
  2206.                  3: Message:='Are you sure that you weren''t cheating ?';
  2207.                  4: Message:='Come in and meet my daughter, son!';
  2208.                  5: Message:='Next time SHOOT the other players !!';
  2209.                  6: Message:='Would you like to see my puppies ?';
  2210.                  7: Message:='Ian Makin has eyebrows just like these !';
  2211.                  9: Message:='<SPEECHLESS>';
  2212.                 10: Message:='What a waste of good hard disk space !';
  2213.                 11: Message:='Does your maw know you''re here ?';
  2214.                 12: Message:='I bet you''re one of Tunstall''s mates !';
  2215.                 13: Message:='Your performance was pure f***ing crap !';
  2216.                 14: Message:='Come up and see my etchings, young man !';
  2217.                 15: Message:='You sure did kick some ass out there !';
  2218.                 16: Message:='I bet you drink Carling Black Label !';
  2219.                 17: Message:='Err... I love you.';
  2220.                 18: Message:='I never liked Dune that much anyway !';
  2221.                 19: Message:='Your mum looks like Yoda from Star Wars !';
  2222.                 20: Message:='I''m buying the rounds tonight son !';
  2223.                 End;
  2224.  
  2225.                  OutTextXY( ((40 - Length(Message))DIV 2) *8,160,Message);
  2226.  
  2227.                  CopySourceBitmap ;
  2228.  
  2229.                  Delay(2000);
  2230.  
  2231.                  Memw[$0040:$1a]:=Memw[$0040:$1c];
  2232.                  TempKey:=ReadKey;
  2233.               End;
  2234.  
  2235.         Until Keydown[1];  { Until key is definitely ESC }
  2236.  
  2237.         {
  2238.         Right, deallocate the memory required for the
  2239.         game & virtual screens.
  2240.         }
  2241.  
  2242.         FreeBitmap(PlanetSeg,PlanetOfs);
  2243.  
  2244.         FreeBitmap(titleBitmapSeg,TitleBitmapOfs);
  2245.  
  2246.         FreeBitmap(EmporerSeg, EmporerOfs);
  2247.  
  2248.         FreeBitmap(ScratchSeg,ScratchOfs);
  2249.         End
  2250.    Else
  2251.        Begin
  2252.        Writeln;
  2253.        Writeln('Memory allocation error! 400K bytes free on heap needed.');
  2254.    End;
  2255. End.
  2256.  
  2257. { I love you all !!! ;) }